From f2cb87d3a947740d180aacb749a5c2fb21aa5eb9 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 22 Aug 2005 20:12:15 +0000 Subject: [PATCH] Implement a clientmessage based scheme for makeing sure that all GTK+ 2005-08-22 Matthias Clasen * gtk/gtkwindow.c (gtk_window_client_event): * gtk/gtkicontheme.c (ensure_valid_themes) (_gtk_icon_theme_check_reload): Implement a clientmessage based scheme for makeing sure that all GTK+ applications notice if an icon theme has been updated. This should prevent multiple versions of an icon theme cache to be mapped in memory at the same time, which can cause excessive memory consumption. (#313156, Chris Lahey) --- ChangeLog | 11 +++++++++++ ChangeLog.pre-2-10 | 11 +++++++++++ ChangeLog.pre-2-8 | 11 +++++++++++ gtk/gtkicontheme.c | 48 ++++++++++++++++++++++++++++++++++++++++++++-- gtk/gtkwindow.c | 25 +++++++++++++++++------- 5 files changed, 97 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 841ba490e0..eb9e32ae91 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2005-08-22 Matthias Clasen + + * gtk/gtkwindow.c (gtk_window_client_event): + * gtk/gtkicontheme.c (ensure_valid_themes) + (_gtk_icon_theme_check_reload): Implement a clientmessage based + scheme for makeing sure that all GTK+ applications notice if an + icon theme has been updated. This should prevent multiple versions + of an icon theme cache to be mapped in memory at the same time, + which can cause excessive memory consumption. (#313156, Chris + Lahey) + 2005-08-22 Matthias Clasen * gtk/gtkicontheme.c (gtk_icon_theme_load_icon): Add a note diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 841ba490e0..eb9e32ae91 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,14 @@ +2005-08-22 Matthias Clasen + + * gtk/gtkwindow.c (gtk_window_client_event): + * gtk/gtkicontheme.c (ensure_valid_themes) + (_gtk_icon_theme_check_reload): Implement a clientmessage based + scheme for makeing sure that all GTK+ applications notice if an + icon theme has been updated. This should prevent multiple versions + of an icon theme cache to be mapped in memory at the same time, + which can cause excessive memory consumption. (#313156, Chris + Lahey) + 2005-08-22 Matthias Clasen * gtk/gtkicontheme.c (gtk_icon_theme_load_icon): Add a note diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 841ba490e0..eb9e32ae91 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,14 @@ +2005-08-22 Matthias Clasen + + * gtk/gtkwindow.c (gtk_window_client_event): + * gtk/gtkicontheme.c (ensure_valid_themes) + (_gtk_icon_theme_check_reload): Implement a clientmessage based + scheme for makeing sure that all GTK+ applications notice if an + icon theme has been updated. This should prevent multiple versions + of an icon theme cache to be mapped in memory at the same time, + which can cause excessive memory consumption. (#313156, Chris + Lahey) + 2005-08-22 Matthias Clasen * gtk/gtkicontheme.c (gtk_icon_theme_load_icon): Add a note diff --git a/gtk/gtkicontheme.c b/gtk/gtkicontheme.c index 360a5c7b44..07f55e03e7 100644 --- a/gtk/gtkicontheme.c +++ b/gtk/gtkicontheme.c @@ -96,6 +96,8 @@ struct _GtkIconThemePrivate GList *dir_mtimes; gulong reset_styles_idle; + + gboolean check_reload; }; struct _GtkIconInfo @@ -1128,7 +1130,7 @@ ensure_valid_themes (GtkIconTheme *icon_theme) { GtkIconThemePrivate *priv = icon_theme->priv; GTimeVal tv; - + if (priv->themes_valid) { g_get_current_time (&tv); @@ -1138,7 +1140,26 @@ ensure_valid_themes (GtkIconTheme *icon_theme) } if (!priv->themes_valid) - load_themes (icon_theme); + { + load_themes (icon_theme); + + if (!priv->check_reload) + { + static GdkAtom atom_iconthemes = GDK_NONE; + GdkEvent *event = gdk_event_new (GDK_CLIENT_EVENT); + int i; + + if (!atom_iconthemes) + atom_iconthemes = gdk_atom_intern ("_GTK_LOAD_ICONTHEMES", FALSE); + + for (i = 0; i < 5; i++) + event->client.data.l[i] = 0; + event->client.data_format = 32; + event->client.message_type = atom_iconthemes; + + gdk_screen_broadcast_client_message (priv->screen, event); + } + } } /** @@ -2937,6 +2958,29 @@ find_builtin_icon (const gchar *icon_name, return min_icon; } +void +_gtk_icon_theme_check_reload (GdkDisplay *display) +{ + gint n_screens, i; + GdkScreen *screen; + GtkIconTheme *icon_theme; + + n_screens = gdk_display_get_n_screens (display); + + for (i = 0; i < n_screens; i++) + { + screen = gdk_display_get_screen (display, i); + + icon_theme = g_object_get_data (G_OBJECT (screen), "gtk-icon-theme"); + if (icon_theme) + { + icon_theme->priv->check_reload = TRUE; + ensure_valid_themes (icon_theme); + icon_theme->priv->check_reload = FALSE; + } + } +} + #ifdef G_OS_WIN32 /* DLL ABI stability backward compatibility versions */ diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 5d40b2711b..7d27c44c4b 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -4648,10 +4648,11 @@ gtk_window_focus_out_event (GtkWidget *widget, } static GdkAtom atom_rcfiles = GDK_NONE; +static GdkAtom atom_iconthemes = GDK_NONE; static void -gtk_window_read_rcfiles (GtkWidget *widget, - GdkEventClient *event) +send_client_message_to_embedded_windows (GtkWidget *widget, + GdkAtom message_type) { GList *embedded_windows; @@ -4664,7 +4665,7 @@ gtk_window_read_rcfiles (GtkWidget *widget, for (i = 0; i < 5; i++) send_event->client.data.l[i] = 0; send_event->client.data_format = 32; - send_event->client.message_type = atom_rcfiles; + send_event->client.message_type = message_type; while (embedded_windows) { @@ -4675,8 +4676,6 @@ gtk_window_read_rcfiles (GtkWidget *widget, gdk_event_free (send_event); } - - gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE); } static gint @@ -4684,10 +4683,22 @@ gtk_window_client_event (GtkWidget *widget, GdkEventClient *event) { if (!atom_rcfiles) - atom_rcfiles = gdk_atom_intern ("_GTK_READ_RCFILES", FALSE); + { + atom_rcfiles = gdk_atom_intern ("_GTK_READ_RCFILES", FALSE); + atom_iconthemes = gdk_atom_intern ("_GTK_LOAD_ICONTHEMES", FALSE); + } if (event->message_type == atom_rcfiles) - gtk_window_read_rcfiles (widget, event); + { + send_client_message_to_embedded_windows (widget, atom_rcfiles); + gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE); + } + + if (event->message_type == atom_iconthemes) + { + send_client_message_to_embedded_windows (widget, atom_iconthemes); + _gtk_icon_theme_check_reload (gtk_widget_get_display (widget)); + } return FALSE; } -- 2.30.2